// SwordSpiritEntity.java
package com.dinzeer.legendreliclib.lib.compat.slashblade.entity;

import com.dinzeer.legendreliclib.lib.compat.slashblade.SlashBladeCompatEntities;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;

import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;

public class SwordSpiritEntity extends Projectile {
    
    // 数据同步
    private static final EntityDataAccessor<Integer> LIFE_TIME = 
        SynchedEntityData.defineId(SwordSpiritEntity.class, EntityDataSerializers.INT);
    private static final EntityDataAccessor<Float> DAMAGE = 
        SynchedEntityData.defineId(SwordSpiritEntity.class, EntityDataSerializers.FLOAT);
    private static final EntityDataAccessor<Integer> PENETRATION_COUNT = 
        SynchedEntityData.defineId(SwordSpiritEntity.class, EntityDataSerializers.INT);
    
    // 状态枚举
    private enum State {
        HOVER,      // 悬停状态
        CIRCLE,     // 绕圈状态
        ATTACK,     // 攻击状态
        RETURN      // 返回状态
    }
    
    private State currentState = State.HOVER;
    private LivingEntity target;
    private UUID ownerUUID;
    private int hoverTicks = 0;
    private int circleTicks = 0;
    private float hoverHeight = 0;
    private Vec3 circleCenter;
    private double circleRadius = 2.0;
    private double circleAngle = 0;
    
    public SwordSpiritEntity(EntityType<? extends SwordSpiritEntity> type, Level level) {
        super(type, level);
        this.noPhysics = true;
    }
    
    public SwordSpiritEntity(Level level, LivingEntity owner, int lifeTime, float damage) {
        this(SlashBladeCompatEntities.SWORD_SPIRIT.get(), level);
        this.setOwner(owner);
        this.setLifeTime(lifeTime);
        this.setDamage(damage);
        this.setPos(owner.getX(), owner.getY() + owner.getBbHeight() * 0.8, owner.getZ());
    }
    
    @Override
    protected void defineSynchedData() {
        this.entityData.define(LIFE_TIME, 200); // 默认存活时间10秒
        this.entityData.define(DAMAGE, 5.0f);   // 默认伤害值
        this.entityData.define(PENETRATION_COUNT, 0);
    }
    
    @Override
    public void tick() {
        super.tick();
        if (level().isClientSide) {
            spawnParticles();
            return; // 跳过后续服务端逻辑
        }
        if (this.tickCount == 1) {
            LivingEntity owner = getOwner();
            if (owner != null) {
                float yaw = owner.getYRot();
                double offsetX = -Mth.sin(yaw * Mth.DEG_TO_RAD) * 1.5;
                double offsetZ = Mth.cos(yaw * Mth.DEG_TO_RAD) * 1.5;
                this.setPos(owner.getX() + offsetX,
                        owner.getY() + owner.getBbHeight() * 0.8,
                        owner.getZ() + offsetZ);
            }
        }
        // 检查存活时间
        if (this.tickCount >= getLifeTime()) {
            this.discard();
            return;
        }

        LivingEntity owner = getOwner();
        if (owner == null) {
            this.discard();
            return;
        }
        // 状态处理
        switch (currentState) {
            case HOVER:
                handleHoverState(owner);
                break;
            case CIRCLE:
                handleCircleState(owner);
                break;
            case ATTACK:
                handleAttackState();
                break;
            case RETURN:
                handleReturnState(owner);
                break;
        }
    }
    
    private void handleHoverState(LivingEntity owner) {
        // 寻找目标
        if (findTarget(owner)) {
            currentState = State.CIRCLE;
            circleCenter = owner.position();
            circleAngle = 0;
            return;
        }

        // 悬停动画
        hoverTicks++;
        float amplitude = 0.1f;
        float frequency = 0.05f;
        hoverHeight = (float) (Math.sin(hoverTicks * frequency) * amplitude);
        
        // 计算悬停位置（在玩家身后）
        float yaw = owner.getYRot();
        double offsetX = -Mth.sin(yaw * Mth.DEG_TO_RAD) * 1.5;
        double offsetZ = Mth.cos(yaw * Mth.DEG_TO_RAD) * 1.5;
        
        double targetX = owner.getX() + offsetX;
        double targetY = owner.getY() + owner.getBbHeight() * 0.8 + hoverHeight;
        double targetZ = owner.getZ() + offsetZ;
        
        // 平滑移动
        double dx = targetX - this.getX();
        double dy = targetY - this.getY();
        double dz = targetZ - this.getZ();
        
        this.setDeltaMovement(dx * 0.2, dy * 0.2, dz * 0.2);
        this.moveTo(this.getX() + dx * 0.2, this.getY() + dy * 0.2, this.getZ() + dz * 0.2);
        

//        this.setYRot(180);
//




    }
    
    private void handleCircleState(LivingEntity owner) {
        circleTicks++;
        if (target == null || !target.isAlive()) {
            currentState = State.RETURN;
            return;
        }
        // 绕圈动画
        circleAngle += 0.1;
        if (circleAngle > Math.PI * 2) {
            circleAngle -= Math.PI * 2;
            
            // 绕圈完成后进入攻击状态
            if (target != null && target.isAlive()) {
                currentState = State.ATTACK;
                this.setDeltaMovement(Vec3.ZERO);
                return;
            }
        }
        
        // 计算绕圈位置
        double targetX = circleCenter.x + Math.cos(circleAngle) * circleRadius;
        double targetY = circleCenter.y + owner.getBbHeight() * 0.8 + Math.sin(circleTicks * 0.1) * 0.2;
        double targetZ = circleCenter.z + Math.sin(circleAngle) * circleRadius;
        
        // 平滑移动
        double dx = targetX - this.getX();
        double dy = targetY - this.getY();
        double dz = targetZ - this.getZ();
        
        this.setDeltaMovement(dx * 0.3, dy * 0.3, dz * 0.3);
        this.moveTo(this.getX() + dx * 0.3, this.getY() + dy * 0.3, this.getZ() + dz * 0.3);
        
        // 面向目标
        if (target != null) {
            Vec3 lookVec = new Vec3(target.getX() - this.getX(), 
                                    target.getY() - this.getY(), 
                                    target.getZ() - this.getZ());
            float yaw = (float) Math.toDegrees(Math.atan2(lookVec.z, lookVec.x)) - 90;
            this.setYRot(yaw);
        }
    }
    
    private void handleAttackState() {
        if (target == null || !target.isAlive()) {
            currentState = State.RETURN;
            return;
        }
        
        // 计算攻击方向
        Vec3 direction = new Vec3(target.getX() - this.getX(), 
                                 target.getY() - this.getY(), 
                                 target.getZ() - this.getZ());
        if (direction.length() < 0.1) {
            direction = new Vec3(0, 0, 1);
        }
        direction = direction.normalize().scale(0.5);
        
        // 移动
        this.setDeltaMovement(direction);
        this.moveTo(this.getX() + direction.x, this.getY() + direction.y, this.getZ() + direction.z);
        
        // 检测碰撞
        AABB collisionBox = this.getBoundingBox().inflate(0.5);
        List<Entity> entities = level().getEntities(this, collisionBox);
        
        for (Entity entity : entities) {
            if (entity == target && !entity.isRemoved()) {
                // 造成伤害
                entity.hurt(this.damageSources().mobAttack(getOwner()), getDamage());
                
                // 穿透计数
                int penetrations = getPenetrationCount() + 1;
                setPenetrationCount(penetrations);
                
                // 检查最大穿透次数
                if (penetrations >= 5) {
                    currentState = State.RETURN;
                } else {
                    // 穿透后绕目标半圈
                    currentState = State.CIRCLE;
                    circleCenter = target.position();
                    circleAngle = 0;
                    circleRadius = target.getBbWidth() + 1.0;
                }
                break;
            }
        }
    }
    
    private void handleReturnState(LivingEntity owner) {
        // 计算返回方向
        Vec3 direction = new Vec3(owner.getX() - this.getX(), 
                                 (owner.getY() + owner.getBbHeight() * 0.8) - this.getY(), 
                                 owner.getZ() - this.getZ());
        if (direction.length() < 1.0) {
            // 返回后重新悬停
            currentState = State.HOVER;
            hoverTicks = 0;
            setPenetrationCount(0);
            return;
        }
        
        direction = direction.normalize().scale(0.4);
        
        // 移动
        this.setDeltaMovement(direction);
        this.moveTo(this.getX() + direction.x, this.getY() + direction.y, this.getZ() + direction.z);
        
        // 面向所有者
        Vec3 lookVec = new Vec3(owner.getX() - this.getX(), 
                                owner.getY() - this.getY(), 
                                owner.getZ() - this.getZ());
        float yaw = (float) Math.toDegrees(Math.atan2(lookVec.z, lookVec.x)) - 90;
        this.setYRot(yaw);
    }
    
    private boolean findTarget(LivingEntity owner) {
        // 在半径8格内寻找目标
        AABB searchArea = owner.getBoundingBox().inflate(8);
        List<LivingEntity> entities = level().getEntitiesOfClass(LivingEntity.class, searchArea, 
            e -> e != owner && e.isAlive() && !e.isAlliedTo(owner));
        
        if (!entities.isEmpty()) {
            target = entities.get(0);
            return true;
        }
        return false;
    }
    
    private void spawnParticles() {
            double offsetX = (random.nextDouble() - 0.5) * 0.1;
            double offsetY = (random.nextDouble() - 0.5) * 0.1;
            double offsetZ = (random.nextDouble() - 0.5) * 0.1;
            
            level().addParticle(ParticleTypes.END_ROD, 
                               this.getX(), 
                               this.getY(), 
                               this.getZ(), 
                               offsetX, offsetY, offsetZ);
    }
    
    // Getters and Setters
    public int getLifeTime() {
        return this.entityData.get(LIFE_TIME);
    }
    
    public void setLifeTime(int lifeTime) {
        this.entityData.set(LIFE_TIME, lifeTime);
    }
    
    public float getDamage() {
        return this.entityData.get(DAMAGE);
    }
    
    public void setDamage(float damage) {
        this.entityData.set(DAMAGE, damage);
    }
    
    public int getPenetrationCount() {
        return this.entityData.get(PENETRATION_COUNT);
    }
    
    public void setPenetrationCount(int count) {
        this.entityData.set(PENETRATION_COUNT, count);
    }
    
    @Nullable
    @Override
    public LivingEntity getOwner() {
        if (ownerUUID != null && level() instanceof ServerLevel) {
            Entity entity = ((ServerLevel) level()).getEntity(ownerUUID);
            return entity instanceof LivingEntity ? (LivingEntity) entity : null;
        }
        return null;
    }
    
    public void setOwner(@Nullable LivingEntity owner) {
        if (owner != null) {
            this.ownerUUID = owner.getUUID();
        }
    }
    
    @Override
    protected void readAdditionalSaveData(CompoundTag tag) {
        if (tag.contains("Owner")) {
            this.ownerUUID = tag.getUUID("Owner");
        }
        this.setLifeTime(tag.getInt("LifeTime"));
        this.setDamage(tag.getFloat("Damage"));
        this.setPenetrationCount(tag.getInt("PenetrationCount"));
        this.currentState = State.values()[tag.getInt("State")];
    }
    
    @Override
    protected void addAdditionalSaveData(CompoundTag tag) {
        if (ownerUUID != null) {
            tag.putUUID("Owner", ownerUUID);
        }
        tag.putInt("LifeTime", getLifeTime());
        tag.putFloat("Damage", getDamage());
        tag.putInt("PenetrationCount", getPenetrationCount());
        tag.putInt("State", currentState.ordinal());
    }
    
    @Override
    public Packet<ClientGamePacketListener> getAddEntityPacket() {
        return NetworkHooks.getEntitySpawningPacket(this);
    }
    
    @Override
    protected boolean canHitEntity(Entity entity) {
        // 只攻击非盟友实体
        return super.canHitEntity(entity) && 
               !entity.isAlliedTo(this.getOwner()) && 
               entity != this.getOwner();
    }
    
    @Override
    public boolean isPickable() {
        return false;
    }
    
    @Override
    public boolean hurt(DamageSource source, float amount) {
        // 剑灵无法被伤害
        return false;
    }
}